/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dataentry;

import com.singularsys.jep.JepException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author i.capurro
 */
public class Form {
    private HashMap <String,Question> questionsHash;
    private ArrayList questionsList;
    private String name;

    public Form(String name) {
        this.name = name;
        Question id = new UniqueQ("id");
        questionsHash = new HashMap();
        questionsList = new ArrayList();
        questionsHash.put(id.getName(), id);
        questionsList.add(id);
    }

    public String getName() {
        return name;
    }

    public ArrayList getQuestionsList() {
        return questionsList;
    }
    
    public void insertQuestion(Question q) throws Exception {
        if (questionsHash.containsKey(q.getName())) {
            throw new Exception("Pregunta " + q.getName() + " duplicada.");
        } else {
            if (q.getQuestionRule() != null) {
                Iterator it = q.getQuestionRule().getVariables().iterator();

                while (it.hasNext()) {
                    String rname = (String) it.next();
                    if (!questionsHash.containsKey(rname)) {
                        throw new Exception ("Error en la definición de la regla de la pregunta " + q.getName() + ".");
                    }
                }
            }
            
            questionsHash.put(q.getName(), q);
            questionsList.add(q);
        }
    }
    
    public boolean isValidValue (String qname, String val) throws Exception {
        Question q = this.questionsHash.get(qname);
        return q.isValidValue(val);
    }
    
    // utiliza la regla del OR, por lo tanto si hay un valor que hace 
    // positiva la regla el resultado es positivo
    private boolean isDisplayableQuestionRecursive (Rule rule, Iterator it) {
        try {
            boolean valid = false;
            if (it.hasNext()) {
                String qname = (String) it.next();
                Question aux = questionsHash.get(qname);
                if (aux.getLength() > 1) {
                    Iterator answers = ((MultipleQ) aux).getAnswers().iterator();
                    if (answers.hasNext()) {
                        while ((!valid) && (answers.hasNext())) {
                            String vstring = (String) answers.next();
                            if (vstring != null) {
                                int value = Integer.parseInt(vstring);
                                rule.addVariable(qname, value);
                            }
                            valid = isDisplayableQuestionRecursive(rule, it);
                        }
                    } else {
                        return false;
                    }
                } else {
                    String vstring = (String) aux.getAnswer();
                    if (vstring != null) {
                        int value = Integer.parseInt (vstring);
                        rule.addVariable(qname, value);
                    }
                    valid = isDisplayableQuestionRecursive(rule, it);
                }
                return valid;
            } else {
                return rule.evaluate();
            }
        } catch (JepException ex) {
            return false;
        }
    }
    
    private boolean isDisplayableQuantityRecursive (Rule rule, Iterator it) {
        try {
            boolean valid;
            if (it.hasNext()) {
                String qname = (String) it.next();
                Question aux = questionsHash.get(qname);
                
                int quant = aux.getAnswers().size();
                rule.addVariable(qname, quant);
                valid = isDisplayableQuantityRecursive(rule,it);
                return valid;
            } else {
                return rule.evaluate();
            }
        } catch (JepException ex) {
            return false;
        }
    }
    
    public boolean isDisplayableQuestion (String qname) throws Exception {
        Question q = this.questionsHash.get(qname);
        Rule rule = q.getQuestionRule();
        Rule qrule = q.getQuantityRule();

        boolean dRule = true;
        boolean qRule = true;
        
        if (rule != null) {
            Iterator dit = rule.getVariables().iterator();
            dRule = isDisplayableQuestionRecursive(rule, dit);
        }
        if (qrule != null) {
            Iterator qit = qrule.getVariables().iterator();
            qRule = isDisplayableQuantityRecursive(qrule, qit);
        }
        
        return (dRule && qRule);
    }
    
    public void save() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        Persistence p = Persistence.getInstance();
        p.saveToTable(name,questionsList);
    }
    
    public List getFormHeader () {
        List list = new ArrayList();
        Iterator it = questionsList.iterator();
        //drop id
        it.next();
        
        while (it.hasNext()) {
            Question q = ((Question) it.next());
            for (int i = 0; i < q.getLength(); i++) {
                String name = q.getName();
                String val = String.valueOf(i+1);
                if (q.getLength() > 1) {
                    name = name + "_" + val;
                }
                list.add(name);
            }
        }
        
        return list;
    }
    
    public Question getQuestion(String name) {
        return questionsHash.get(name);
    }
    
}
